package br.com.sovi.persistence;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.openinsula.arena.hibernate.entity.BaseEntity;
import org.springframework.util.ObjectUtils;

/**
 * Um ponto representa uma posição geográfica.
 * 
 * @author João Galli
 */
@Entity
public class Ponto extends BaseEntity<Long> {
	private static final long serialVersionUID = 1L;

	/**
	 * Data no sistema.
	 */
	@Temporal(TemporalType.TIMESTAMP)
	private Date data = new Date();

	/**
	 * Data capturada no dispositivo.
	 */
	@Temporal(TemporalType.TIMESTAMP)
	private Date dataDispositivo;

	@Column(nullable = false)
	private Double latitude;

	@Column(nullable = false)
	private Double longitude;

	@ManyToOne
	@JoinColumn(name = "dispositivo_fk")
	private Dispositivo dispositivo;

	@ManyToOne
	@JoinColumn(name = "cerca_fk")
	private Cerca cerca;

	public Ponto() {
	}

	public Ponto(Double latitude, Double longitude) {
		super();
		this.latitude = latitude;
		this.longitude = longitude;
	}

	public Ponto(Date dataDispositivo, Double latitude, Double longitude) {
		super();
		this.dataDispositivo = dataDispositivo;
		this.latitude = latitude;
		this.longitude = longitude;
	}

	@Override
	public String toString() {
		return String.format("[%s: id= %s], dataDispositivo = %s, ll = %s,%s", getClass().getName(), ObjectUtils
				.nullSafeToString(getId()), ObjectUtils.nullSafeToString(dataDispositivo), ObjectUtils
				.nullSafeToString(latitude), ObjectUtils.nullSafeToString(longitude));
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}

		if (obj == null || !getClass().isAssignableFrom(obj.getClass())) {
			return false;
		}

		Ponto other = (Ponto) obj;

		return new EqualsBuilder().append(this.data, other.data).append(this.latitude, other.latitude).append(
				this.longitude, other.longitude).isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(data).append(latitude).append(longitude).toHashCode();
	}

	public Date getData() {
		return data;
	}

	public void setData(Date data) {
		this.data = data;
	}

	public Date getDataDispositivo() {
		return dataDispositivo;
	}

	public void setDataDispositivo(Date dataDispositivo) {
		this.dataDispositivo = dataDispositivo;
	}

	public Double getLatitude() {
		return latitude;
	}

	public void setLatitude(Double latitude) {
		this.latitude = latitude;
	}

	public Double getLongitude() {
		return longitude;
	}

	public void setLongitude(Double longitude) {
		this.longitude = longitude;
	}

	public void setDispositivo(Dispositivo dispositivo) {
		this.dispositivo = dispositivo;
	}

	public Dispositivo getDispositivo() {
		return dispositivo;
	}

	public void setCerca(Cerca cerca) {
		this.cerca = cerca;
	}

	public Cerca getCerca() {
		return cerca;
	}

}
